package com.oaker.hours.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.oaker.common.core.domain.entity.SysDept;
import com.oaker.common.core.domain.entity.SysUser;
import com.oaker.common.exception.ServiceException;
import com.oaker.common.utils.DateUtils;
import com.oaker.hours.doman.columns.Columns;
import com.oaker.hours.doman.dto.MhArchiveQueryDTO;
import com.oaker.hours.doman.entity.MhArchive;
import com.oaker.hours.doman.entity.MhArchiveHour;
import com.oaker.hours.doman.entity.MhConfig;
import com.oaker.hours.doman.entity.MhUserHour;
import com.oaker.hours.doman.vo.MhArchiveDetailVO;
import com.oaker.hours.doman.vo.MhArchiveVO;
import com.oaker.hours.doman.vo.UserHourListVO;
import com.oaker.hours.doman.vo.UserHourStatVO;
import com.oaker.hours.enums.UserHourFillStatusEnum;
import com.oaker.hours.mapper.MhArchiveHourMapper;
import com.oaker.hours.mapper.MhArchiveMapper;
import com.oaker.hours.mapper.MhConfigMapper;
import com.oaker.hours.service.MhArchiveHourService;
import com.oaker.hours.service.MhArchiveService;
import com.oaker.hours.service.MhUserHourService;
import com.oaker.system.service.ISysUserService;
import com.oaker.common.annotation.DataScope;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static com.oaker.common.utils.SecurityUtils.getUserId;
import static com.oaker.common.utils.SecurityUtils.getUsername;
import static java.util.stream.Collectors.toList;


@Service
@Slf4j
public class MhArchiveServiceImpl extends ServiceImpl<MhArchiveMapper, MhArchive> implements MhArchiveService {

    @Autowired
    private  MhArchiveMapper archiveMapper;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private MhUserHourService userHourService;

    @Autowired
    private MhArchiveHourService mhArchiveHourService;


    @Override
    public List<MhArchiveVO> queryList( MhArchiveQueryDTO mhArchiveQueryDTO) {
        LocalDate startDate = mhArchiveQueryDTO.getStartDate();
        LocalDate endDate = mhArchiveQueryDTO.getEndDate();

        if (endDate ==null) {
            endDate = LocalDate.now();
        }
        if  (startDate ==null) {
            startDate = endDate.minusMonths(3);
        }

        String start =DateUtils.localToMonth(startDate);
        String end = DateUtils.localToMonth(endDate);
        //log.info("endDate:{}",endDate);

        log.info("end:{}",end);
        //查询所有的归档记录
        EntityWrapper<MhArchive> wrapper = new EntityWrapper<>();
        wrapper.eq(Columns.MhArchive.deptId,mhArchiveQueryDTO.getDeptId() )
                .and()
                .between(Columns.MhArchive.archiveDate, start, end);

        //
        List<MhArchive> mhArchivesList = baseMapper.selectList(wrapper);

        Map<String, MhArchive> archiveMap = mhArchivesList.stream().collect(Collectors.toMap(MhArchive::getArchiveDate, mhArchive -> mhArchive));
        Set<String > archDates =  mhArchivesList.stream().map(MhArchive::getArchiveDate).collect(Collectors.toSet());

        long between = ChronoUnit.MONTHS.between(startDate,endDate);
        // List<LocalDate> allDay = Stream.iterate(startDate, localDate -> localDate.plusMonths(1)).limit(between + 1).collect(toList());
        //log.info("between:{}",between);
        List<LocalDate> allMonth = Stream.iterate(endDate, localDate -> localDate.minusMonths(1)).limit(between ).collect(toList());
        log.info("allMonth:{}",allMonth);

        LocalDate now = LocalDate.now();

        MhArchiveVO mhArchiveVO;
        //返回的结果列表
        List<MhArchiveVO> list = new ArrayList<>();
        for (LocalDate dayDate: allMonth) {
            String day = DateUtils.localToMonth(dayDate);
            mhArchiveVO = new MhArchiveVO();

            if (dayDate.isAfter(now)) {
                continue;
            }
            mhArchiveVO.setArchiveDate(day);

            if (archDates.contains(day)) {
                MhArchive mhArchive = archiveMap.get(day);
                BeanUtils.copyProperties(mhArchive,mhArchiveVO);

                mhArchiveVO.setStatus(true);
                log.info("mharchiveis:{}",mhArchiveVO);
                list.add(mhArchiveVO);
                continue;
            }
            mhArchiveVO.setStatus(false);
            mhArchiveVO.setDeptId((long) mhArchiveQueryDTO.getDeptId());
            list.add(mhArchiveVO);
        }

        return list;
    }

    @Override
    @Transactional
    public long create(Long deptId, String archiveDate) {
        LocalDate now = LocalDate.now();

        String nowMonth =  DateUtils.localToMonth(now);
        log.info("nowMonth:{},",nowMonth);
        log.info("archiveDate:{},",archiveDate);

        if (archiveDate.equals(nowMonth)) {
            throw new ServiceException("本月不能归档，请等待本月结束");
        }



        //String monthString =  DateUtils.localToMonth(month);

        //查询是否已存在归档
        EntityWrapper<MhArchive> queryWrapper = new EntityWrapper<>();
        queryWrapper.eq(Columns.MhArchive.deptId, deptId)
                .eq(Columns.MhArchive.archiveDate, archiveDate);
        Integer count = baseMapper.selectCount(queryWrapper);

        if (count >0) {
            throw new ServiceException("当前月份已归档，请勿重复归档");
        }
        Date createTime = new Date();

        MhArchive  archive = new MhArchive();
        archive.setArchiveDate(archiveDate)
                .setDeptId(deptId)
                .setCreateUser(getUserId())
                .setCreateTime(createTime);

        archiveMapper.insert(archive);

        //查询该部门下所有人员
//        SysDept  dept  = new SysDept();
//        dept.setDeptId(deptId);
//        SysUser queryuser = new SysUser();
//        queryuser.setDept(dept);
//
//        List<SysUser> userList = userService.selectUserList(queryuser);
//        //
//        //查询该月的所有记录
//        //1.将时间字符串转为时间类型
//        DateTimeFormatter fmt = new DateTimeFormatterBuilder()
//                .appendPattern("yyyy-MM")
//                .parseDefaulting(ChronoField.DAY_OF_MONTH, 1)
//                .toFormatter();
//
//        LocalDate month = LocalDate.parse(archiveDate,fmt);
//
//        log.info("________________________________________________________");
//        log.info("month:{}",month);
//
//
//        for (SysUser user: userList) {
//            List<UserHourStatVO> myHourStat = userHourService.getUserHourMonthList(month,user.getUserId());
//
//            if (myHourStat.size() ==0 || myHourStat ==null) {
//                continue;
//            }
//            List<MhArchiveHour>  mhArchiveHourList = new ArrayList<>();
//            for (UserHourStatVO userHourStatVO :myHourStat) {
//                if (userHourStatVO.getId() !=null) {
//                    MhArchiveHour mhArchiveHour = new MhArchiveHour();
//                    mhArchiveHour.setArchiveId(archive.getId());
//                    mhArchiveHour.setHourId(userHourStatVO.getId());
//                    mhArchiveHourList.add(mhArchiveHour);
//                }
//            }
//            mhArchiveHourService.saveBatch(mhArchiveHourList);
//        }

        return archive.getId();
    }

    @Override
    public MhArchiveDetailVO query(Long archiveId) {
        MhArchiveDetailVO mhArchiveDetailVO = new MhArchiveDetailVO()  ;
        MhArchive mhArchive = archiveMapper.query(archiveId);
        BeanUtils.copyProperties(mhArchive,mhArchiveDetailVO);
        List<MhArchiveHour> hourList =   mhArchiveHourService.queryByArchiveId(mhArchive.getId());
        mhArchiveDetailVO.setHourList(hourList);
        return mhArchiveDetailVO;
    }

    @Override
    public void deleteById(Long archiveId) {
        baseMapper.deleteById(archiveId);

    }

    @Override
    public Integer selectCount(EntityWrapper<MhArchive> queryWrapper) {
        return baseMapper.selectCount(queryWrapper);
    }
}
